package com.example.myproject.java8.fanxing;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by xi on 2018/9/16.
 * 上界<? extends T>不能往里存，只能往外取。总结
 *
 */
public class Test {
    static class Fruit{}

    static class Apple extends  Fruit{}

    static class RedApple extends  Apple{};

    /**
     * 原因：
     *为什么上述问题中使用上界通配符后就出现编译出错的问题：
     List<? extends Fruit> list 表示当前列表中可以存储 Fruit以及Fruit的子类，
     从这层含义来看，似乎上述不应该报错，因为存储的对象是符合list定义限定数据范围的。
     但是事实上确实报错了，这主要是Java出于泛型安全性的考虑。
     因为上界通配符<? extends T> 表示的是一个类型范围，
     编译器无法确定List所持有的具体类型，所以无法安全的向其中添加对象但是可以添加null,因为null 可以表示任何类型。

     所以List 的add 方法不能添加任何有意义的元素，但是可以接受现有的子类型List<Apple> 赋值。
     因此对于上界边界符，Java编译器限制了其存数据。即：<? extends T> 不能存数据，但是可以取数据，
     而使用get方法取出来的数据只能赋值为T类型的变量。
     T value = list.get(0)  接口==子类，这是多态的体现；
     */


    private static void testUpperBound(){
        List<Apple> list0 = new ArrayList<>();
        List<? extends Fruit> list =  list0;
        //  List<?> list = new ArrayList();
        Fruit f1 = new Fruit();
        Apple a1 = new Apple();
        //list.add(f1);//1报错
        //list.add(a1)//2报错
        list.add(null);
        Fruit a = list.get(0);
    }

    /**
     * <? super T> 下界通配符： 表示T以及T的超类，可以存数据，但是只能取出Object的数据
     * 5处报错原因：因为list的定义限定存储数据的类型最低是apple，
     * 因此对于编译器来说，只有存入低于或者等于apple的数据对象才能认为是数据安全的。
     * 所以存入fruit对象时才会报错。
     *而同样的 如果要在当前list中取出数据时，因为限定的是最低类型，而最高可以达到Object类，所以，在get数据时只能赋值给Object对象。
     * （假设Java中没有Object类的定义，这里也许就不被允许get数据）
     *
     */
    public static void testLowBound(){
        List <? super Apple> appList = new ArrayList();
       //  appList.add(new Fruit());5 //报错
        appList.add(new Apple());
        appList.add(new RedApple());

       // Apple s1 = appList.get(0);//报错因为是Apple的某个父类，所以必须繁华Object.

    }

    public static void main(String[] args) {
        List <Fruit> appList = new ArrayList();
        appList.add(new Apple());
        appList.add(new RedApple());

        RedApple f = new RedApple();
        Apple a = new Apple();

        RedApple g = (RedApple)a;




    }


}
